/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package percussiongenerator.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import percussiongenerator.gui.view.TimeLineView;
import percussiongenerator.gui.view.View;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.ResourceBundle;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfonia.connect5.basics.BasicValueNode;
import org.jfonia.connect5.basics.MutableValueNode;
import org.jfonia.view.main.LeadSheet;
import org.jfonia.model.Sequence;
import org.jfonia.model.StaffCollection;
import org.jfonia.model.elements.Clef;
import org.jfonia.model.elements.Tone;
import org.jfonia.pitch.Base40;
import org.jfonia.pitch.MusicalInterval;
import org.jfonia.view.panels.LeadSheetPanel;
import percussiongenerator.gui.view.LeadSheetView;
import percussiongenerator.gui.view.MetronomeView;
import percussiongenerator.gui.view.PianorollView;
import percussiongenerator.languages.ILanguageDependent;
import percussiongenerator.model.Track;

/**
 *
 * @author Jannes Plyson
 */
public class TrackPanel extends JPanel implements ILanguageDependent{
    private Track track;
    MutableValueNode<View> selectedView;
    MutableValueNode<ArrayList<Integer>> selectedInterval;
    public TrackPanel(Track track, MutableValueNode<View> selectedView){        
        this.track = track;
        this.setBackground(Color.WHITE);
        this.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));        
        this.selectedView = selectedView;
        selectedInterval = new BasicValueNode<ArrayList<Integer>>(null);
        addView(TimeLineView.class);        
        //testLeadSheetPanel();
    }

        public void testLeadSheetPanel(){
            Sequence<Clef> clefSequence = new Sequence<Clef>(Clef.class);
            Clef clef = new Clef();
            clef.setDifference(track.getStaff().getLength());
            clefSequence.add(clef);
            track.getStaff().addSequence(clefSequence);
            Sequence<Tone> seq = track.getStaff().getToneSequence();
            for(int i = 0; i < seq.size(); i++){
                ((Tone)seq.getIntervalFromIndex(i)).setBase40Rank(Base40.toBase40(new MusicalInterval(0, 0)));
            }
            final JFrame frame = new JFrame();
            JPanel panel = new JPanel();
            frame.setContentPane(panel);
            panel.setLayout(new BorderLayout());           
            MutableValueNode<Double> xNode = new BasicValueNode<Double>(0.0);
            MutableValueNode<Double> yNode = new BasicValueNode<Double>(0.0);
            final MutableValueNode<Double> width = new BasicValueNode<Double>(700.0);
            final MutableValueNode<Double> height = new BasicValueNode<Double>(700.0);
            LeadSheet leadSheet = new LeadSheet();
            LeadSheetPanel leadSheetPanel = new LeadSheetPanel(xNode, yNode, width, height);
            panel.add(leadSheetPanel,BorderLayout.SOUTH);
            leadSheetPanel.setLeadSheet(leadSheet);
            StaffCollection staffCollection = new StaffCollection();
            leadSheet.addStaffCollection(staffCollection);
            staffCollection.addStaff(track.getStaff());
            new Thread(new Runnable() {
                public void run() {
                    frame.setVisible(true);
                    frame.setSize(new Dimension(500,500));
                    width.setValue(200.0);
                    height.setValue(200.0);
                }
            }).start();
        }

    public Track getTrack(){
        return track;
    }

    public final void addView(Class cl){
        if(!getViewClasses().contains(cl)){
            View v = null;
            if(cl == TimeLineView.class){                
                v = new TimeLineView(track,selectedView,selectedInterval);                
            }else if(cl == MetronomeView.class){
                v = new MetronomeView(track, selectedView,track.getTrackCollection().getMidiPlayer());
            }else if(cl == PianorollView.class){
                v = new PianorollView(track, selectedView,selectedInterval);
            }else if(cl == LeadSheetView.class){
                v = new LeadSheetView(track, selectedView,selectedInterval);
            }
            if(v != null){
                track.getTimeNode().addObserver(v);
                this.add(v);
                this.revalidate();
                updateTrackCollection();
            }
        }
    }

    public ArrayList<Class> getViewClasses(){
        ArrayList<Class> classes = new ArrayList<Class>();
        Component[] components = getComponents();
        for(Component c : components){
            if(c instanceof View){
                classes.add(c.getClass());
            }
        }
        return classes;
    }

    public ArrayList<View> getViews(){
        ArrayList<View> views = new ArrayList<View>();
        Component[] components = getComponents();
        for(Component c : components){
            if(c instanceof View){
                views.add((View)c);
            }
        }
        return views;
    }

    public void removeView(Class cl){
        Component[] components = getComponents();
        for(Component c : components){
            if(c.getClass() == cl){
                track.getTimeNode().removeObserver((View)c);
                remove(c);
            }
        }
        this.revalidate();
        updateTrackCollection();
    }

    public long getLength(){        
        return track.getPerformanceLength();
    }

    public void updateLanguage(ResourceBundle labels) {
        ArrayList<View> views = getViews();
        for(int i=0; i < views.size(); i++){
            views.get(i).updateLanguage(labels);
        }
    }    

    public void timeUpdated(long time) {                
        ArrayList<View> views = getViews();
        for(int i = 0; i < views.size(); i++){
            views.get(i).repaint();
        }
    }    

    private void updateTrackCollection(){
        if(track.getTrackCollection() != null){
            track.getTrackCollection().trackUpdated(track);
        }
    }
    
}
